package com.meritit.portal.util;
/**
 * 对接入业务系统的用户密码进行加密
 * @author 张钊儒
 * @since 2008-6-17
 * @revise 2008-8-8
 */
public class Encrypt {
	/**
	 * 静太方法直接调用
	 * @param str 要加密的字符串
	 * @return String 加密后字符串
	 */
	public static String merger(String key,String str) {
		int i = (str.length() < key.length()) ? str.length() : key.length();
		String temp = "";

		if (i == str.length() && i != key.length()) {
			temp = key.substring(i, key.length());
		} else if (i == key.length() && i != str.length()) {
			temp = str.substring(i, str.length());
		}
		int[] bt = new int[i];
		for (int j = 0; j < i; j++) {
			bt[j] = (int) str.charAt(j) + (int) key.charAt(j);
		}
		int[] bt2 = new int[temp.length()];
		for(int j=0;j<temp.length();j++){
			bt2[j]=(int)temp.charAt(j);
		}
		StringBuffer sb = new StringBuffer(bt.length);
		StringBuffer sb2 = new StringBuffer(bt2.length);
		String sTemp;
		for (int k = 0; k < bt.length; k++) {
			sTemp = Integer.toHexString(bt[k]);
			if (sTemp.length() < 2)
				sb.append(0);
			sb.append(sTemp.toUpperCase());
		}
		for (int k = 0; k < bt2.length; k++) {
			sTemp = Integer.toHexString(bt2[k]);
			if (sTemp.length() < 2)
				sb2.append(0);
			sb2.append(sTemp.toUpperCase());
		}
		sb.append(sb2);
		return sb.toString();

	}
	/**
	 * 相同加密方法的第二个程序
	 * @param str
	 * @return
	 */
	public static String encrypt(String key,String str){
		//都转换为整型数组
		int[] keyArray=stringToArray(key); 
		int[] sourceArray=stringToArray(str);
		int codeMaxLength=keyArray.length<sourceArray.length?sourceArray.length:keyArray.length;
		int codeMinLength=keyArray.length<sourceArray.length?keyArray.length:sourceArray.length;
		int[] codeArray=new int[codeMaxLength];
		String[] codeHexArray=new String[codeMaxLength];
		int ikey=0;
		int isource=0;
		int icode=0;
		//公共部分运算
		for(;icode<codeMinLength;icode++,ikey++,isource++){
			codeArray[icode]=keyArray[ikey]+sourceArray[isource];
		}
		//非公共部分接上面
		if(keyArray.length<sourceArray.length){
			for(;isource<sourceArray.length;isource++,icode++){
				codeArray[icode]=sourceArray[isource];
			}
		}else {
			for(;ikey<keyArray.length;ikey++,icode++){
				codeArray[icode]=keyArray[ikey];
			}
		}
		//转换为16进制字符串
		StringBuffer sb=new StringBuffer();
		for(int i=0;i<icode;i++){
			codeHexArray[i]=Integer.toHexString(codeArray[i]);
			sb.append(codeHexArray[i]);
		}
		
		return sb.toString();
	}
	/**
	 * 解密方法
	 * @param str 加密后字符串
	 * @return String  加密前字符串
	 * @throws Exception
	 */
	public static String decrypt (String key,String str) throws Exception{
		int[] keyArray=stringToArray(key);  //分别转为整型数组
		int[] codeArray=hexToArray(str);
		int[] sourceArray=new int[codeArray.length];
		int ikey=0;
		int icode=0;
		
		for(;icode<codeArray.length && ikey<keyArray.length;icode++,ikey++){
			//对码值进行�?�运算，到原码长度时�?出�??
			if(codeArray[icode]-keyArray[ikey]==0)break;
			sourceArray[icode]=codeArray[icode]-keyArray[ikey];
		}
		//原码长度>key长度时，将剩余码接上�?
		if(keyArray.length<codeArray.length&& icode<codeArray.length){
			for(;icode<codeArray.length ;icode++){
				sourceArray[icode]=codeArray[icode];
			}
		}
		StringBuffer sb=new StringBuffer();
		//将分解后的asc码转成字符放入sb�?
		for(int i=0;i<icode;i++){
			sb.append((char)sourceArray[i]);
		}
		return sb.toString();
	}
	/**
	 * 把16进制字符串转换为整型数组，即asc码数组
	 * @param str
	 * @return
	 * @throws Exception
	 */
	public static int[] hexToArray(String str) throws Exception{
		int length=str.length();
		//对数据做校验，如果数据格式不正确，抛出异常
		if(length%2!=0){
			throw new Exception("错误的数据格式！");
		}
		int []all=new int[length/2];
		//每两位转换为1个asc码
		for(int i=0;i<all.length;i++){
			all[i]=Integer.parseInt(str.substring(i*2,i*2+2), 16);
		}
		return all;
	}
	/**
	 * 将字符串转换为整型数组，即asc码的数组
	 * @param str 
	 * @return  
	 */
	public static int[] stringToArray(String str){
		int bt[] = new int[str.length()];
		for(int j=0;j<str.length();j++){
			bt[j]=(int)str.charAt(j);
		}
		return bt;
	}
	
	/**
	 * 主函数测试用
	 * @param args
	 */
	public static void main(String[] args) {
		String key = DateUtils.getCurrDateStr();
	    String str = "portal";
		try{
		    String res = encrypt(key,str);
		    System.out.println("加密前字符串为:"+str);
		    System.out.println("加密后字符串为:"+res);
		    System.out.println("解码后符串为:"+decrypt(key,res));
		}catch(Exception e){
		    System.out.println("对字符串"+str+"进行处理失败");
		}
	}
}
